home *** CD-ROM | disk | FTP | other *** search
- #if defined(FW_DEBUG)
- // This entire file is for debugging only
- //========================================================================================
- //
- // File: FWTrace.cpp
- // Release Version: $ 1.0d1 $
- //
- // Creation Date: 3/28/94
- //
- // Copyright: © 1994 by Apple Computer, Inc., all rights reserved.
- //
- //========================================================================================
-
- #ifndef FWTRACE_H
- #include "FWTrace.h"
- #endif
-
- #ifndef FWPRIDEB_H
- #include "FWPriDeb.h"
- #endif
-
- #ifndef FWPRISTR_H
- #include "FWPriStr.h"
- #endif
-
- #ifndef FWPRIMEM_H
- #include "FWPriMem.h"
- #endif
-
- #ifdef FW_BUILD_MAC
-
- #include <StdDef.h>
- #include <LowMem.h>
-
- #endif
-
- #if defined(FW_BUILD_WIN) && !defined(FWSYMFIL_H)
- #include "FWSymFil.h"
- #endif
-
- #if defined(FW_BUILD_WIN) && !defined(FWWTRACE_H)
- #include "FWWTrace.h"
- #endif
-
- #ifdef __ZTC__
- #include <stdlib.h>
- extern "C"
- {
- char* unmangle_ident(const char* ident);
- };
- #endif
-
- //========================================================================================
- // CLASS FW_CTraceRuntime
- //========================================================================================
-
- char FW_CTraceRuntime::gPrefixChar[2] = {'>', '<'};
-
- //----------------------------------------------------------------------------------------
- // FW_CTraceRuntime::Initialize
- //----------------------------------------------------------------------------------------
- short FW_CTraceRuntime::Initialize(FW_CDebugStream *traceStream)
- {
- FW_SPrivTraceGlobals& globals = FW_CPrivTraceTaskGlobals::GetTraceGlobals();
- short successful = 0;
-
- globals.gTraceEnabled = 0;
-
- if (traceStream != NULL)
- {
- globals.gTraceStream = traceStream;
- #ifdef FW_BUILD_WIN16
- void* pTraceBuffer = ::FW_PrimitiveAllocateBlock(32000);
- FW_PRIV_ASSERT(pTraceBuffer != NULL);
- globals.gTraceBuffer = pTraceBuffer;
- successful = pTraceBuffer != NULL;
-
- FW_CPrivWinDebugModuleList::Initialize();
- #endif
- }
-
- return successful;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CTraceRuntime::Terminate
- //----------------------------------------------------------------------------------------
- void FW_CTraceRuntime::Terminate()
- {
- FW_SPrivTraceGlobals& globals = FW_CPrivTraceTaskGlobals::GetTraceGlobals();
- globals.gTraceStream = NULL;
- #ifdef FW_BUILD_WIN16
- ::FW_PrimitiveFreeBlock(globals.gTraceBuffer);
- globals.gTraceBuffer = NULL;
-
- FW_CPrivWinDebugModuleList::Terminate();
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CTraceRuntime::StartTrace
- //----------------------------------------------------------------------------------------
- // We increment the counter each time StartTrace is called.
- // Tracing is only enabled when the counter is above 0.
- void FW_CTraceRuntime::StartTrace()
- {
- FW_SPrivTraceGlobals& globals = FW_CPrivTraceTaskGlobals::GetTraceGlobals();
- unsigned short enableCount = globals.gTraceEnabled;
- enableCount++;
- FW_PRIV_ASSERT(enableCount>0); // if fails, StartTrace called too many times!
- globals.gTraceEnabled = enableCount;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CTraceRuntime::StopTrace
- //----------------------------------------------------------------------------------------
- void FW_CTraceRuntime::StopTrace()
- {
- FW_SPrivTraceGlobals& globals = FW_CPrivTraceTaskGlobals::GetTraceGlobals();
- unsigned short enableCount = globals.gTraceEnabled;
- FW_PRIV_ASSERT(enableCount>0); // if fails, StopTrace called too many times!
- enableCount--;
- globals.gTraceEnabled = enableCount;
- }
-
- //========================================================================================
- // Windows specific functions
- //========================================================================================
-
- //----------------------------------------------------------------------------------------
- // FW_CTraceRuntime::TraceIn
- //----------------------------------------------------------------------------------------
- // Called every time a function is entered
- #ifdef FW_BUILD_WIN16
- void FW_CTraceRuntime::TraceIn()
- {
- FW_SPrivTraceGlobals& globals = FW_CPrivTraceTaskGlobals::GetTraceGlobals();
- unsigned short enableCount = globals.gTraceEnabled;
- if (enableCount == 0)
- return;
-
- void* pTraceBuffer = globals.gTraceBuffer;
- FW_CDebugStream * traceStream = globals.gTraceStream;
-
- if (pTraceBuffer != NULL && traceStream != NULL)
- {
- // Walk the stack
- HANDLE hModule;
- WORD wSegment;
- WORD wOffset;
-
- FW_PrivWinGetCallerInfo(&hModule, NULL, &wSegment, &wOffset, 3);
-
- DumpOneLine(*traceStream, ">> ", hModule, wSegment, wOffset);
-
- WORD * pwTraceBuffer = (WORD *)pTraceBuffer;
- *pwTraceBuffer++ = wSegment;
- *pwTraceBuffer++ = wOffset;
- *pwTraceBuffer++ = hModule;
- globals.gTraceBuffer = pwTraceBuffer;
- }
- }
- #endif
-
- //----------------------------------------------------------------------------------------
- // FW_CTraceRuntime::TraceOut
- //----------------------------------------------------------------------------------------
- // Called every time a function is exited
- #ifdef FW_BUILD_WIN16
- void FW_CTraceRuntime::TraceOut()
- {
- FW_SPrivTraceGlobals& globals = FW_CPrivTraceTaskGlobals::GetTraceGlobals();
- unsigned short enableCount = globals.gTraceEnabled;
- if (enableCount == 0)
- return;
-
- void* pTraceBuffer = globals.gTraceBuffer;
- FW_CDebugStream * traceStream = globals.gTraceStream;
-
- if (pTraceBuffer != NULL && traceStream != NULL)
- {
- // Walk the stack
- HANDLE hModule;
- WORD wSegment;
- WORD wOffset;
-
- WORD * pwTraceBuffer = (WORD *)pTraceBuffer;
- hModule = *--pwTraceBuffer;
- wOffset = *--pwTraceBuffer;
- wSegment = *--pwTraceBuffer;
- globals.gTraceBuffer = pwTraceBuffer;
-
- DumpOneLine(*traceStream, "<< ", hModule, wSegment, wOffset);
- }
- }
- #endif
-
- //----------------------------------------------------------------------------------------
- // FW_CTraceRuntime::DumpOneLine
- //----------------------------------------------------------------------------------------
- #ifdef FW_BUILD_WIN16
- void FW_CTraceRuntime::DumpOneLine(FW_CDebugStream& traceStream,
- const char* pzPrefix,
- unsigned hModule,
- unsigned wSegment,
- unsigned wOffset)
- {
- int fSymbolFound=0, fModuleFound=0;
- char zSymbol[128];
- char zModule[10];
-
- fModuleFound = FW_CPrivWinDebugModuleList::GetModuleName(hModule, zModule);
- fSymbolFound = FW_CPrivWinDebugModuleList::FindSymbol(hModule, wSegment, wOffset, sizeof zSymbol, zSymbol);
-
- #ifdef __ZTC__
- if(fSymbolFound)
- {
- char* pzUnm = unmangle_ident(zSymbol);
- if(pzUnm)
- {
- FW_PrimitiveStringCopy(zSymbol, pzUnm);
- ::free(pzUnm);
- }
- }
- #endif
-
- traceStream << pzPrefix << " ";
- traceStream << (fModuleFound ? (char *) zModule : "?") << ": ";
- traceStream << ((void*) wSegment) << ":" << ((void*) wOffset) << " ";
- traceStream << (fSymbolFound ? (char *) zSymbol : "?") << EndLine;
- }
- #endif
-
-
- //========================================================================================
- // Macintosh specific functions
- //========================================================================================
-
- // Disable tracing so that we don't end up doing a circular trace in this code.
- // This code has been placed at the end of the file so that the rest of the
- // runtime library can be traced if necessary.
- #pragma trace off
-
- //----------------------------------------------------------------------------------------
- // GetCurStackBase
- //----------------------------------------------------------------------------------------
- // Returns a pointer to the current stack base. This routine is used for sanity
- // checking functions being traced. If the PC goes beyond the stackbase,
- // then something is wrong.
- #ifdef FW_BUILD_MAC
- inline void* GetCurStackBase()
- {
- return *((void**)LMGetCurStackBase());
- }
- #endif
-
- //----------------------------------------------------------------------------------------
- // GetCurStackFramePtr
- //----------------------------------------------------------------------------------------
- // Returns a pointer to the current stack frame. This function is used to determine
- // the return address for the function.
- #ifdef FW_BUILD_MAC
- pascal Ptr GetCurStackFramePtr() = {0x2e8e};
- #endif
-
-
- //----------------------------------------------------------------------------------------
- // GetReturnAddress
- //----------------------------------------------------------------------------------------
- // Returns a pointer to the return address of the function being traced. This address
- // is then used to find the function name, which is stored at the end of the function.
- #ifdef FW_BUILD_MAC
- inline void* GetReturnAddress(Ptr FramePtr)
- {
- return (*(void **) ((long)FramePtr + 4));
- }
- #endif
-
- //----------------------------------------------------------------------------------------
- // odd - returns TRUE if value is an odd number, otherwise returns FALSE.
- //----------------------------------------------------------------------------------------
- #ifdef FW_BUILD_MAC
- inline Boolean odd(long value)
- {
- return (value & 0x00000001);
- }
- #endif
-
- //----------------------------------------------------------------------------------------
- // GetProcName
- //----------------------------------------------------------------------------------------
- // Returns the name of the procedure or function in which pc points. If it is in a
- // method, then it return"s the name of the method"s class in className. procName is
- // assumed to be at least 255 characters.
- #ifdef FW_BUILD_MAC
- pascal void GetProcName(void* pc, char* procName)
- {
- procName[0] = '\0';
- #ifdef _MPWCFRONT
- // (MLH) ??? Need to have a symantec C++ implementation of this. Especially
- // since we don't use mpw cfront anymore.
-
- if (pc != NULL && !odd((long) pc))
- {
- void* nextPC;
- char localProcName[256];
-
- // Get the routine name from the end of the module that was
- // entered. localProcName will contain a null-terminated
- // pascal string containing the mangled name.
- Ptr limit = (Ptr) ((ptrdiff_t) pc + 32767);
- while (!endOfModule(pc, limit, localProcName, &nextPC))
- {
- if (pc >= limit)
- {
- procName[0] = '\0';
- localProcName[0] = '\0';
- return;
- }
- else
- pc = (void *) ((ptrdiff_t) pc + 2);
- }
-
- char cProcName[256];
-
- // unmangle the localProcName to something more recognizable,
- // then put it in procName.
- if (unmangle(cProcName, &(localProcName[1]), 255) < 1)
- FW_PrimitiveStringCopy(procName, &(localProcName[1]));
- else
- FW_PrimitiveStringCopy(procName, cProcName);
- }
- #endif
- }
- #endif
-
- //----------------------------------------------------------------------------------------
- // TraceIn
- //----------------------------------------------------------------------------------------
- // Called when a routine is entered. Writes the routine name out to the current logfile.
- // If no logfile exists, then nothing happens.
- #ifdef FW_BUILD_MAC
- void FW_CTraceRuntime::TraceIn()
- {
- FW_SPrivTraceGlobals& globals = FW_CPrivTraceTaskGlobals::GetTraceGlobals();
- IncrTraceDepth();
- unsigned short enableCount = globals.gTraceEnabled;
- if (enableCount > 0)
- {
- FW_CDebugStream* traceStream = globals.gTraceStream;
-
- if (traceStream != NULL)
- {
- char procName[256];
- void* returnAddress = GetReturnAddress(GetCurStackFramePtr());
-
- GetProcName(returnAddress, procName);
-
- DumpOneLine(*traceStream, globals.gTraceDepth, kStepIn, procName);
- }
- }
-
- }
- #endif
-
- //----------------------------------------------------------------------------------------
- // TraceOut
- //----------------------------------------------------------------------------------------
- // Called when a routine is exited. Writes the routine name out to the current logfile.
- // If no logfile exists, then nothing happens.
- #ifdef FW_BUILD_MAC
- void FW_CTraceRuntime::TraceOut()
- {
- FW_SPrivTraceGlobals& globals = FW_CPrivTraceTaskGlobals::GetTraceGlobals();
- unsigned short enableCount = globals.gTraceEnabled;
- if (enableCount > 0)
- {
- FW_CDebugStream* traceStream = globals.gTraceStream;
-
- if (traceStream != NULL)
- {
- void* curStackFrame = GetReturnAddress(GetCurStackFramePtr());
- char procName[256];
-
- GetProcName(curStackFrame, procName);
-
- DumpOneLine(*traceStream, globals.gTraceDepth, kStepOut, procName);
- }
- }
- DecrTraceDepth();
- }
- #endif
-
- //----------------------------------------------------------------------------------------
- // DumpOneLine
- //----------------------------------------------------------------------------------------
- // Writes the strings pzPrefix and procName out to the file specified by traceStream.
- // traceStream must point to a valid file. pzPrefix is used by TraceIn and TraceOut to
- // determine whether a function is being entered or exited. procName contains the
- // name of the function being entered or exited.
- #ifdef FW_BUILD_MAC
- void FW_CTraceRuntime::DumpOneLine(FW_CDebugStream& traceStream,
- unsigned short depth,
- StepInOut direction,
- const char* procName)
- {
- const unsigned short maxIndentDepth=20;
- if (depth > maxIndentDepth)
- depth = maxIndentDepth;
- for (short i=0; i<depth; i++)
- traceStream << gPrefixChar[direction];
- traceStream << procName << EndLine;
- }
- #endif
-
- //----------------------------------------------------------------------------------------
- // FW_CTraceRuntime::IncrTraceDepth
- //----------------------------------------------------------------------------------------
- #ifdef FW_BUILD_MAC
- void FW_CTraceRuntime::IncrTraceDepth()
- {
- FW_SPrivTraceGlobals& globals = FW_CPrivTraceTaskGlobals::GetTraceGlobals();
- globals.gTraceDepth++;
- FW_PRIV_ASSERT(globals.gTraceDepth>0); // if fails, IncrTraceDepth called too many times!
- }
- #endif
-
- //----------------------------------------------------------------------------------------
- // FW_CTraceRuntime::DecrTraceDepth
- //----------------------------------------------------------------------------------------
- #ifdef FW_BUILD_MAC
- void FW_CTraceRuntime::DecrTraceDepth()
- {
- FW_SPrivTraceGlobals& globals = FW_CPrivTraceTaskGlobals::GetTraceGlobals();
- globals.gTraceDepth--;
- FW_PRIV_ASSERT(globals.gTraceDepth>=0); // if fails, DecrTraceDepth called too many times!
- }
- #endif
-
- #endif